package com.rainbowelephant.fun.fitness;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.support.v4.app.NavUtils;

/**
 * 
 * @author 	Kyle Lewis
 * @date 	December 3, 2012
 * @version	8
 *
 */
public class GPSActivity extends Activity implements LocationListener {

	private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
	private static final long MIN_TIME_BW_UPDATES = 1000 * 3; // 3 seconds
	protected LocationManager locationManager;
	private boolean isGPSEnabled = false;
	private boolean isRunning = false;
	private boolean stopped = false;
	private double prevLongitude;
	private double prevLatitude;
	private double curLongitude;
	private double curLatitude;
	private double distance;
	long startTime;
	long endTime;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_gps);

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		distance = 0.0;

		if (isGPSEnabled) {
			locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER,
					MIN_TIME_BW_UPDATES,
					MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
		}
		else {
			((TextView)findViewById(R.id.GPSWarning)).setText("Please enable the GPS.");
		}


	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_gps, menu);
		return true;
	}


	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	public void start(View view) {
		startTime = System.currentTimeMillis();
		isRunning = true;
		stopped = false;

		((TextView)findViewById(R.id.distance)).setText("0.000 miles");
		((TextView)findViewById(R.id.pace)).setText("99:59 min/mi");
		
		((Button)findViewById(R.id.startButton)).setVisibility(View.GONE);
		((Button)findViewById(R.id.stopButton)).setVisibility(View.VISIBLE);
	}

	public void stop(View view) {
		endTime = System.currentTimeMillis();
		isRunning = false;
		stopped = true;

		((TextView)findViewById(R.id.speed)).setText("0.00 mph");
		
		((Button)findViewById(R.id.stopButton)).setVisibility(View.GONE);
		((Button)findViewById(R.id.resetButton)).setVisibility(View.VISIBLE);
	}

	public void reset(View view) {
		startTime = 0;
		endTime = 0;
		distance = 0.0;
		prevLongitude = 0.0;
		prevLatitude = 0.0;
		stopped = false;

		((TextView)findViewById(R.id.distance)).setText("");
		((TextView)findViewById(R.id.pace)).setText("");
		
		((Button)findViewById(R.id.resetButton)).setVisibility(View.GONE);
		((Button)findViewById(R.id.startButton)).setVisibility(View.VISIBLE);
	}

	public void onLocationChanged(Location loc) {
		double spd = ((int) (loc.getSpeed() * 2.2369 * 100.0)) / 100.0;
		String speed = String.valueOf(spd);

		if (speed.substring(speed.indexOf('.') + 1).length() == 1) {
			speed += "0";
		}
		
		speed += " mph";
		
		if (!isRunning && !stopped) {
			((ProgressBar)findViewById(R.id.GPSProgress)).setVisibility(View.GONE);
			((TextView)findViewById(R.id.GPSWarning)).setVisibility(View.GONE);
			((Button)findViewById(R.id.startButton)).setVisibility(View.VISIBLE);
			
			curLongitude = loc.getLongitude();
			curLatitude = loc.getLatitude();

			((TextView)findViewById(R.id.speed)).setText(speed);

			return;
		}
		else if (stopped) {
			
		}
		else {
			prevLongitude = curLongitude;
			prevLatitude = curLatitude;

			curLongitude = loc.getLongitude();
			curLatitude = loc.getLatitude();

			distance += getDistance();
			String formattedDistance = String.valueOf(((double) ((int) (distance * 1000.0)) / 1000.0));
			
			int paceMins = (int) (60.0 / spd);
			int paceSecs = (int) (((60.0 / spd) - paceMins) * 60.0);
			String pace = "";
			
				if (paceSecs == 60) {
					paceSecs = 0;
					paceMins++;
				}
				
				if (paceMins < 10) {
					pace += "0";
				}
				pace += paceMins + ":";
				
				if (paceSecs < 10) {
					pace += "0";
				}
				pace += paceSecs + " min/mi";
				
				if (paceMins > 99) {
					pace = "99:59 min/mi";
				}
			
			if (formattedDistance.substring(formattedDistance.indexOf('.') + 1).length() == 1) {
				formattedDistance += "00";
			}
			else if (formattedDistance.substring(formattedDistance.indexOf('.') + 1).length() == 2) {
				formattedDistance += "0";
			}
			else {
				((TextView)findViewById(R.id.distance)).setText(formattedDistance + " miles");
			}
			((TextView)findViewById(R.id.speed)).setText(speed);
			((TextView)findViewById(R.id.pace)).setText(pace);
		}
	}

	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	private double getDistance() {
		double R = 3961; // Radius of the earth in miles
		double dLat = Math.toRadians(curLatitude - prevLatitude);
		double dLon = Math.toRadians(curLongitude - prevLongitude); 

		double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
				Math.cos(Math.toRadians(prevLatitude)) * 
				Math.cos(Math.toRadians(curLatitude)) * 
				Math.sin(dLon/2) * Math.sin(dLon/2); 
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 

		return R * c; // Distance in miles
	}

}
